package org.example.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.example.SignatureStatus;
import org.example.config.AppProperties;
import org.example.domain.beans.JwtParseInfo;
import org.springframework.stereotype.Component;

import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Base64;
import java.util.Date;

@Component
public class JwtUtils {

    private Log logger = LogFactory.getLog(JwtUtils.class);

    public static final String ACCESS_TOKEN_KEY = "access_token";
    public static final String REFRESH_TOKEN_KEY = "refresh_token";

    private Key accessKey;
    private Key refreshKey;
    private long accessJwtExpire; // access_token 的过期时间
    private long refreshJwtExpire; // frefsh_token 过期时间


    public JwtUtils(AppProperties appProperties) {
        accessKey = new SecretKeySpec(Base64.getDecoder().decode(appProperties.getJwt().getKey()), "HmacSHA512");
        refreshKey = new SecretKeySpec(Base64.getDecoder().decode(appProperties.getJwt().getRefreshKey()), "HmacSHA512");
        accessJwtExpire = appProperties.getJwt().getAccessJwtExpire();
        refreshJwtExpire = appProperties.getJwt().getRefreshJwtExpire();
    }

    // 验证 access_token
    public JwtParseInfo validateAccessJwt(String jwt) {
        return validateJwt(jwt, accessKey);
    }

    // 验证 refresh_token
    public JwtParseInfo validateRefreshJwt(String jwt) {
        return validateJwt(jwt, refreshKey);
    }

    // 验证token
    private JwtParseInfo validateJwt(String jwt, Key key) {
        JwtParseInfo jpi = new JwtParseInfo();
        try {
            Claims claims = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(jwt).getBody();
            jpi.setClaims(claims);
            jpi.setSignatureStatus(SignatureStatus.correct);
            return jpi;   // 正常
        } catch (ExpiredJwtException exception) {
            logger.info("jwt过期了");
            jpi.setSignatureStatus(SignatureStatus.expired);
            return jpi; // 过期了
        } catch (MalformedJwtException | io.jsonwebtoken.security.SignatureException | UnsupportedJwtException exception) {
            logger.error("jwt可能被篡改了");
            jpi.setSignatureStatus(SignatureStatus.tamper);
            return jpi;
        }
    }

    // 创建access_token
    public String createAccessToken(String username) {
        return createToken(username, accessJwtExpire, accessKey);
    }

    // 创建refresh_token
    public String createRefreshToken(String username) {
        return createToken(username, refreshJwtExpire, refreshKey);
    }

    /**
     * 创建token
     * @param username  用户名
     * @param expire    jwt 的失效的事件
     * @Param key       是用来签名, 就是用来封装签名字符串
     * @return
     */
    private static String createToken(String username, long expire, Key key) {
        return Jwts.builder()
                .setSubject(username)  // 设置当前的用于
                .setIssuedAt(new Date())      // Jwt的创建时间
                .setExpiration(new Date(System.currentTimeMillis() + expire))   // 过期时间
                .signWith(key, SignatureAlgorithm.HS512)
                .compact();  // 返回签名对应的 字符串
    }

    public static void main(String[] args) {
        System.out.println(createToken("a", 10000, Keys.secretKeyFor(SignatureAlgorithm.HS512)));
    }
}
